% TODO proof-reading
\subsubsection{Second example}

Another simple crackme example:

\begin{lstlisting}[style=customjava]
public class password
{
	public static void main(String[] args)
	{
		System.out.println("Please enter the password");
		String input = System.console().readLine();
		if (input.equals("secret"))
			System.out.println("password is correct");
		else
			System.out.println("password is not correct");
	}
}
\end{lstlisting}

Let's load it in IDA:

\begin{figure}[H]
\centering
\myincludegraphics{Java_and_NET/java/13_patching/2/1.png}
\caption{IDA}
\end{figure}

We see here the \TT{ifeq} instruction which does the job.

Its name stands for \IT{if equal}, and this is misnomer, a better name would be \TT{ifz} (\IT{if zero}), i.e, 
if value at \ac{TOS} is zero, then do the jump.

In our example, it jumps if the password is not correct 
(the \TT{equals} method returns \TT{False}, which is 0).

The very first idea is to patch this instruction.

There are two bytes in \TT{ifeq} opcode, which encode the jump offset.

To make this instruction a NOP, we must set the 3rd byte to the value of 3 
(because by adding 3 to the current address we will always jump to the next instruction,
since the \TT{ifeq} instruction's length is 3 bytes):


\begin{figure}[H]
\centering
\myincludegraphics{Java_and_NET/java/13_patching/2/2.png}
\caption{IDA}
\end{figure}

That doesn't work (JRE 1.7):

\begin{lstlisting}
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 24
Exception Details:
  Location:
    password.main([Ljava/lang/String;)V @21: ifeq
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0000000: b200 0212 03b6 0004 b800 05b6 0006 4c2b
    0000010: 1207 b600 0899 0003 b200 0212 09b6 0004
    0000020: a700 0bb2 0002 120a b600 04b1
  Stackmap Table:
    append_frame(@35,Object[#20])
    same_frame(@43)

        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
        at java.lang.Class.getMethod0(Class.java:2856)
        at java.lang.Class.getMethod(Class.java:1668)
        at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
\end{lstlisting}

But it must be mentioned that it worked in JRE 1.6.

We can also try to replace to all 3 \TT{ifeq} opcode bytes with zero bytes (\ac{NOP}), 
and it still won't work.

Seems like there are more stack map checks in JRE 1.7.


OK, we'll replace the whole call to the \TT{equals} method with the \TT{iconst\_1} instruction 
plus a pack of \ac{NOP}s:


\begin{figure}[H]
\centering
\myincludegraphics{Java_and_NET/java/13_patching/2/3.png}
\caption{IDA}
\end{figure}

1 needs always to be in the \ac{TOS} when the \TT{ifeq} instruction is executed, 
so \TT{ifeq} would never jump.


This works.
